<?php

namespace app\api\controller;

use app\common\controller\Api;
use think\Db;
use think\facade\Log;

/**
 * 网络监测接口
 */
class Quality extends Api
{

    //如果$noNeedLogin为空表示所有接口都需要登录才能请求
    //如果$noNeedRight为空表示所有接口都需要验证权限才能请求
    //如果接口已经设置无需登录,那也就无需鉴权了
    //
    // 无需登录的接口,*表示全部
    protected $noNeedLogin = [];
    // 无需鉴权的接口,*表示全部
    protected $noNeedRight = [];

    public function quality(){
        $game = $this->links('game'); 
        $video = $this->links('video'); 
        $webpage =  $this->links('webpage'); 
        $filedownload = $this->links('filedownload'); 
        $basedlink = $this->links('basedlink'); 
        $quality = '-';
        if($basedlink != '-'){
            $quality = floatval($quality) + $basedlink*config('quality')['propertyname_percent']['basedlink'];
        }
        if($filedownload != '-'){
            $quality = floatval($quality) + $filedownload*config('quality')['propertyname_percent']['filedownload'];
        }
        if($video != '-'){
            $quality = floatval($quality) + $video*config('quality')['propertyname_percent']['video'];
        }
        if($webpage != '-'){
            $quality = floatval($quality) + $webpage*config('quality')['propertyname_percent']['webpage'];
        }
        if($game != '-'){
            $quality = floatval($quality) + $game*config('quality')['propertyname_percent']['game'];
        }
        $quality = round($quality,0);
        return $quality;
    }

    public function link($snap='')
    {
        //处理参数
        $propertyname = $this->request->post('propertyname');
        if($snap){
            switch ($snap) {
                case 'app':
                    $propertyname = 'basedlinkdetails';
                    break;
                default:
                    $propertyname = $snap;
                    break;
            }
        }
        if(!$propertyname){
            $this->error(__('Missed parameters'));
        }
        if(!in_array($propertyname, config('quality')['propertyname'])){
            $this->error(__('Invalid parameters'));
        }
        $propertyname_send = $propertyname;
        if($propertyname == 'basedlinkdetails_sort'){
            $propertyname_send = 'basedlinkdetails';
        }

        $gradename = $this->request->post('gradename');
        if($snap){
            $gradename = '每天';
        }
        if(!$gradename){
            $gradename = '5分钟';
        }
        if(!in_array($gradename, config('quality')['gradename'])){
            $this->error(__('Invalid parameters'));
        }

        $starttime = $this->request->post('starttime');
        if($snap){
            $starttime = date('Y-m-d 00:00:00');
        }
        if(!$starttime){
            $starttime = date('Y-m-d H:i:s',time()-24*60*60);
        }
        $endtime = $this->request->post('endtime');
        if($snap || !$endtime){
            $endtime = date('Y-m-d H:i:s');
        }

        //拼输入参数
        $userinfo = $this->auth->getUserinfo();
        $id = $userinfo['id'];
        $probe = Db::name('user_config')->where('user_id',$id)->value('probe');
        // dump($probe);exit;
        if(!$probe){
            $this->error(__('Please configure the probe interface'));
        }
        $probe_arr = json_decode($probe,true); //格式化一下
        if( !(isset($probe_arr['url']) && $probe_arr['url']) ){
            $this->error(__('Please configure the probe interface : url'));
        }
        if( !(isset($probe_arr['mission']) && $probe_arr['mission']) ){
            $this->error(__('Please configure the probe interface : mission'));
        }
        $propertyname_config = $propertyname;
        if($propertyname == 'basedlinkdetails' || $propertyname == 'basedlinkdetails_sort'){
            $propertyname_config = 'basedlink';
        }
        if( !(isset($probe_arr['mission'][$propertyname_config]) && $probe_arr['mission'][$propertyname_config]) ){
            $this->error(__('Please configure the probe interface : mission'));
        }
        if(!is_json(json_encode($probe_arr['mission'][$propertyname_config]))){
            $this->error(__('Please configure the probe interface : mission(json)'));
        }
        // dump('xxxxx'.$propertyname_send);
        $input_arr = array(
            'mission'=> $probe_arr['mission'][$propertyname_config],
            'propertyName'=>$propertyname_send,
            'gradeName'=>$gradename,
            'startTime'=>$starttime,
            'endTime'=>$endtime,
        );
        // dump($input_arr);exit;
        $data_string = json_encode($input_arr);
        $url = $probe_arr['url'];
        Log::record(microtime().'发送拨测地址：'.$url,'API');
        Log::record(microtime().'发送拨测参数：'.$data_string,'API');
        //发请求拿数据
        $curlopt = array(
            CURLOPT_HTTPHEADER=>array ('Content-Type: application/json; charset=utf-8', 'Content-Length: ' . strlen ( $data_string ) ),
            CURLOPT_TIMEOUT=>config('quality')['timeout'],
        );
        $data = curl_post($url, $data_string, $curlopt);
        Log::record(microtime().'拨测接口返回：'.$data,'API');
        $data = json_decode($data,true);

        if(isset($data['status']) && $data['status'] == 'fail'){
            $this->error($data['mess']);
        }else{
            if(isset($data['data'])){
                // dump($data['data']);exit;
                if($snap){
                    return $this->format_index_data($data['data'],$snap);
                }else if($propertyname == 'basedlinkdetails' || $propertyname == 'basedlinkdetails_sort'){
                    //处理数据，匹配应用
                    $data['data'] = $this->format_basedlinkdetails_data($data['data'],$gradename,$propertyname);
                    // dump($data['data']);
                    $this->success('', $data['data']);
                }else{
                    $this->success('', $data['data']);
                }
            }else{
                //没取到数据的情况
                $this->error(__('the probe interface return has not data key'));
            }
        }
    }


    //首页指标单独处理
    public function links($snap='')
    {
        //处理参数
        $propertyname = $this->request->post('propertyname');
        if($snap){
            switch ($snap) {
                case 'app':
                    $propertyname = 'basedlinkdetails';
                    break;
                default:
                    $propertyname = $snap;
                    break;
            }
        }
        $propertyname_send = $propertyname;
        if($propertyname == 'basedlinkdetails_sort'){
            $propertyname_send = 'basedlinkdetails';
        }
        $gradename = $this->request->post('gradename');
        if($snap){
            $gradename = '每天';
        }
        if(!$gradename){
            $gradename = '5分钟';
        }

        $starttime = $this->request->post('starttime');
        if($snap){
            $starttime = date('Y-m-d 00:00:00');
        }
        if(!$starttime){
            $starttime = date('Y-m-d H:i:s',time()-24*60*60);
        }
        $endtime = $this->request->post('endtime');
        if($snap || !$endtime){
            $endtime = date('Y-m-d H:i:s');
        }

        //拼输入参数
        $userinfo = $this->auth->getUserinfo();
        $id = $userinfo['id'];
        $probe = Db::name('user_config')->where('user_id',$id)->value('probe');
        // dump($probe);exit;
        $probe_arr = json_decode($probe,true); //格式化一下
        if( !(isset($probe_arr['url']) && $probe_arr['url']) ){
            //$this->error(__('Please configure the probe interface : url'));
            $probe_arr['url'] = '';
        }
        if( !(isset($probe_arr['mission']) && $probe_arr['mission']) ){
            $probe_arr['mission'] = '';
            //$this->error(__('Please configure the probe interface : mission'));
        }
        $propertyname_config = $propertyname;
        if($propertyname == 'basedlinkdetails' || $propertyname == 'basedlinkdetails_sort'){
            $propertyname_config = 'basedlink';
        }
        if( !(isset($probe_arr['mission'][$propertyname_config]) && $probe_arr['mission'][$propertyname_config]) ){
            $probe_arr['mission'][$propertyname_config] = '';
            //$this->error(__('Please configure the probe interface : mission'));
        }
        // dump('xxxxx'.$propertyname_send);
        $input_arr = array(
            'mission'=> $probe_arr['mission'][$propertyname_config],
            'propertyName'=>$propertyname_send,
            'gradeName'=>$gradename,
            'startTime'=>$starttime,
            'endTime'=>$endtime,
        );
        // dump($input_arr);exit;
        $data_string = json_encode($input_arr);
        $url = $probe_arr['url'];
        Log::record(microtime().'发送拨测地址：'.$url,'API');
        Log::record(microtime().'发送拨测参数：'.$data_string,'API');
        //发请求拿数据
        $curlopt = array(
            CURLOPT_HTTPHEADER=>array ('Content-Type: application/json; charset=utf-8', 'Content-Length: ' . strlen ( $data_string ) ),
            CURLOPT_TIMEOUT=>config('quality')['timeout'],
        );
        $data = curl_post($url, $data_string, $curlopt);
        Log::record(microtime().'拨测接口返回：'.$data,'API');
        $data = json_decode($data,true);

        if(isset($data['status']) && $data['status'] == 'fail'){
                return -1;
        }else{
            if(isset($data['data'])){
                // dump($data['data']);exit;
                if($snap){
                    return $this->format_index_data($data['data'],$snap);
                }else if($propertyname == 'basedlinkdetails' || $propertyname == 'basedlinkdetails_sort'){
                    //处理数据，匹配应用
                    $data['data'] = $this->format_basedlinkdetails_data($data['data'],$gradename,$propertyname);
                    // dump($data['data']);
                    $this->success('', $data['data']);
                }else{
                    $this->success('', $data['data']);
                }
            }else{
                //没取到数据的情况
                return -1;
            }
        }
    }




    //格式化链路详情的数据，匹配应用名，留下库里有的应用名
    public function format_basedlinkdetails_data($data,$gradename,$propertyname){
        $apptype = $this->request->post('apptype');
        $appname = $this->request->post('appname');
        $typenum = $this->request->post('typenum');
        $appnum = $this->request->post('appnum');
        if(!$typenum){
            $typenum = config('quality')['basedlinkdetails_sort_type_num'];
        }
        if(!$appnum){
            $appnum = config('quality')['basedlinkdetails_sort_app_num'];
        }
        $data_arr = array();
        $name_type = $this->get_apps('name_type');
        if(isset($data[0]) && is_array($data[0]) && count($data[0]) > 0){
            $item = $data[0];//只拿第一个linkid的
            if(isset($item['details']) && is_array($item['details']) && count($item['details'])>0 ){
                //拿到库里所有的应用
                $apps = $this->get_apps('name');
                // $data_arr = array();
                foreach ($item['details'] as $key => $value) {
                    if(in_array($value['linkRouteName'],$apps)){
                        $item = array();
                        if($gradename == '每天' || $gradename == '每周' || $gradename == '每月'){
                            if( $propertyname == 'basedlinkdetails_sort' ){
                                //分类型，排序
                                $type = $this->get_type_icon($value['linkRouteName'], 'type', $name_type);
                                $data_arr[$type][$value['linkRouteName']] = $value['item'][0]['netWorkDelay'];
                            }else{
                                $item['name'] = $value['linkRouteName'];
                                $item['shaking'] = $value['item'][0]['shaking'];
                                $item['netWorkDelay'] = $value['item'][0]['netWorkDelay'];
                                $item['packageLoss'] = (double)round(100 - $value['item'][0]['equipmentSuccessRate'],2);
                                $data_arr[] = $item;
                            }
                        }else if($gradename == '5分钟'|| $gradename == '半小时'|| $gradename == '1小时' || $gradename == '4小时'){

                            if(!$apptype){
                                $this->error(__('Missed parameters'));
                            }
                            if(!$appname){
                                $this->error(__('Missed parameters'));
                            }
                            $is_valid_app = $this->has_app($appname, $apptype, $name_type);
                            if(!$is_valid_app){
                                $this->error(__('Invalid parameters'));
                            }
                            if($value['linkRouteName'] != $appname){
                                continue;
                            }
                            $shaking = array();
                            $netWorkDelay = array();
                            $packageLoss = array();
                            foreach ($value['item'] as $key2 => $value2) {
                                $temp = array();
                                $temp['timeInterval'] = $value2['timeInterval'];
                                $temp['value'] = $value2['netWorkDelay'];
                                $netWorkDelay[] = $temp;

                                $temp = array();
                                $temp['timeInterval'] = $value2['timeInterval'];
                                $temp['value'] = $value2['shaking'];
                                $shaking[] = $temp;

                                $temp = array();
                                $temp['timeInterval'] = $value2['timeInterval'];
                                $temp['value'] = (double)round(100 - $value2['equipmentSuccessRate'],2);
                                $packageLoss[] = $temp;
                            }
                            $data_arr['shaking'] = $shaking;
                            $data_arr['netWorkDelay'] = $netWorkDelay;
                            $data_arr['packageLoss'] = $packageLoss;
                        }
                    }
                }
                
                if($gradename == '每天' || $gradename == '每周' || $gradename == '每月'){
                    if( $propertyname == 'basedlinkdetails_sort' ){
                        // $data_arr = array(
                        //     '即时通讯1'=>array(
                        //         "tcp1"=>110,
                        //         "tcp2"=>80,
                        //         "tcp"=>2,
                        //         "tcp4"=>15,
                        //         "tcp5"=>15
                        //     )
                        // );
                        //格式化$data_arr，取4个大类，每大类4个小类 取数据排序字段
                        $data_arr = $this->format_sort($data_arr);
                        //格式化
                        $temp_arr = array();
                        $i = 0;
                        foreach ($data_arr as $key => $value) {
                            $temp = array();
                            $temp['name'] = $key;
                            if($i++ > ($typenum-1) ){ 
                                break;
                            }
                            $j = 0;
                            foreach ($value as $key2 => $value2) {
                                if($j++ > ($appnum-1) ){ 
                                    break;
                                }
                                $icon = $this->get_type_icon($key2, 'icon', $name_type);
                                if($icon){
                                    $temp['icon'] = request()->domain().$icon;
                                }else{
                                    $temp['icon'] = '';
                                }
                                $temp_temp = array();
                                $temp_temp['name'] = $key2;
                                $temp_temp['value'] = $value2;
                                $temp_temp['level'] = $this->get_level('主要应用连接状态', $value2);
                                $temp['list'][] = $temp_temp;
                            }
                            $temp_arr[] = $temp;
                        }
                        $data_arr = $temp_arr;
                    }
                }
            }
        }
        if($propertyname == 'basedlinkdetails'){
            if($gradename == '5分钟'|| $gradename == '半小时'|| $gradename == '1小时' || $gradename == '4小时'){
                if(count($data_arr) == 0){
                    $data_arr = json_decode('{}');
                }
            }
        }
        return $data_arr;
    }

    public function format_index_data($data, $snap){
        if($snap == 'app'){
            // dump($data);exit;
            if(isset($data[0]['details']) && is_array($data[0]['details'])){
                foreach ($data[0]['details'] as $key => $value) {
                    $all_score[$value['linkRouteName']] = isset($value['item'][0]['qualityScore']) ? $value['item'][0]['qualityScore'] : 0;
                    // $all_score[] = isset($value['item'][0]['qualityScore']) ? $value['item'][0]['qualityScore'] : 0;
                }
                //这里只要配置在白名单里应用，返回的应用不是全要
                $score = $this->getDbAppScore($all_score);
                // $score = $all_score;
                if(count($score) > 0 ){
                    $row=[];
                    $avg = round(array_sum($score)/count($score),2);
                    $row['score']=$avg;
                    $row['appqualitys']=$this->get_level('应用质量', $avg);
                    return $row;
                }else{
                    return -1;
                }
            }else{
                return -1;
            }
        }else{
            $score = isset($data[0]['item'][0]['qualityScore']) ? $data[0]['item'][0]['qualityScore'] : -1;
            // dump($score.'====');
            return $score;
        }
    }
    //这里只要配置在白名单里应用，返回的应用不是全要
    public function getDbAppScore($all_score){
        $score = array();
        $keys = array_keys($all_score);
        $rs = Db::name('app')->field('name')->where('name','in',$keys)->order('sort desc')->select();
        foreach ($rs as $key => $value) {
            $score[] = $all_score[$value['name']];
        }
        return $score;
    }

    public function format_sort($data){
        $return_arr = array();
        $keys = array_keys($data);
        $rs = Db::name('app_type')->field('name')->where('name','in',$keys)->order('sort desc')->select();
        // dump($rs);exit;
        foreach ($rs as $key => $value) {
            $apps = array();
            $app_rs = Db::name('app')->field('name')->where('name', 'in',array_keys($data[$value['name']]))->order('sort desc')->select();
            foreach ($app_rs as $key2 => $value2) {
                $apps[$value2['name']] = $data[$value['name']][$value2['name']];
            }
            $return_arr[$value['name']] = $apps;
        }
        return $return_arr;
    }

    public function apps(){
        $rs = Db::name('app')
        ->alias('a')
        ->field('a.name,t.name as type')
        ->join('app_type t', 'a.app_type_id = t.id', 'left')
        ->select();
        $rs2 = array();
        foreach ($rs as $key => $value) {
            $rs2[$value['type']][] = $value['name']; 
        }
        $data_arr = array();
        foreach ($rs2 as $type => $value) {
            $item = array();
            $item['name'] = $type;
            foreach ($value as $key2 => $value2) {
                $item['list'][] = $value2;
            }
            $data_arr[] = $item;
        }
        $this->success('', $data_arr);
    }

    public function has_app($appname, $apptype, $name_type){
        foreach ($name_type as $key => $value) {
            if($value['name'] == $appname && $value['type'] == $apptype){
                return true;
            }
        }
        return false;
    }

    //应用名可以相同，所以不能以应用名为键值
    public function get_type_icon($appname, $flag, $name_type){
        foreach ($name_type as $key => $value) {
            if($value['name'] == $appname){
                if($flag == 'type'){
                    return $value['type'];
                }else if($flag == 'icon'){
                    return $value['icon'];
                }
            }
        }
        return '';
    }
}
